/*************************************************************************
	> File Name: sigaltstack.c
	> Author: Angel Criss
	> Blog: blog.abbycin.tk 
	> Created Time: Sat 21 Jun 2014 03:12:51 PM CST
 ************************************************************************/
//这里的altstack是留给内核向进程发送信号用的,是进程不至于空间耗尽被饿死,\而是在空间耗尽前内核发送信号将其杀死
#define _GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>

void dealing(int sig)
{
    printf("This is the end of this proccess\nbecause the kernel send me a SIGSEGV singal\n");
    _exit(SIGSEGV); // including in "unistd.h" be used to exit proccess
}

void expand(int count)
{
    char exp[1000]; // try to make a big space to run out of the stack
    printf("it's now at \e[33m%10p\e[0m\n",&exp[0]);
    expand(count+1);
}

int main(int argc, char *argv[])
{
    stack_t space;
    sigset_t set;
    struct sigaction act;

    if(sigemptyset(&set)==-1)
    {
        perror("sigemptyset:");
        raise(15);
    }

    space.ss_sp=malloc(SIGSTKSZ);
    space.ss_size=SIGSTKSZ;
    space.ss_flags=SS_ONSTACK; // this clear that the proccess is runnig on the altstack

    if(sigaltstack(&space,NULL)==-1)
    {
        perror("sigaltstack:");
        raise(2);
    }
/*
 * this sigaction() fuction should after sigaltstack() fuction
 */
    act.sa_handler=dealing;
    act.sa_mask=set;
    act.sa_flags=SA_ONSTACK; // this is needed !!!

    if(sigaction(SIGSEGV,&act,NULL)==-1)
    {
        perror("sigacton:");
        raise(15);
    }
    expand(1); //recursive invok itself
}
